import {AfterViewInit, Component, ElementRef, HostBinding, Input, Renderer2} from '@angular/core';
import { ReplaySubject } from 'rxjs';
import { IndexableObject } from 'sigma/core/types/indexable';
import { BreakpointObserver, MediaMatcher } from '@angular/cdk/layout';
import { gridResponsiveMap, NsBreakpointKey } from 'sigma/core/types/breakpoint';


export type NsJustify = 'start' | 'end' | 'center' | 'space-around' | 'space-between';
export type NsAlign = 'top' | 'middle' | 'bottom';

@Component({
  selector: 'ns-row',
  template: `
    <ng-content></ng-content>
  `,
  styleUrls: ['./grid.component.scss']
})
export class GridRowComponent implements AfterViewInit {

  readonly actualGutter$ = new ReplaySubject<[number | null, number | null]>(1);
  // 垂直方向排列方式
  @Input() nsAlign: NsAlign | null = null; 
  // 水平方向排列方式
  @Input() nsJustify: NsJustify | null = null;
  // 支持数字 | 响应式布局{ xs: 8, sm: 16, md: 24} | 上下间距和左右间距数组 | 响应式上下左右间距数组
  @Input() nsGutter: number | IndexableObject | [number, number] | [IndexableObject, IndexableObject] | null = null;
  // grid-template-columns: 100px auto 100px 参数控制布局
  @Input() nsGrid: string | null = null;

  @HostBinding('class.sigma-row') default = true;
  @HostBinding('style')
  get setStyle (): Object {
    const style = {}
    if (this.nsGrid) {
      style['grid-template-columns'] = this.nsGrid;
    }
    if (this.nsAlign) {
      style['align-items'] = this.nsAlign;
    }
    if (this.nsJustify) {
      style['justify-content'] = this.nsJustify;
    }
    return style;
  }

  constructor(
    public elementRef: ElementRef,
    public render: Renderer2,
    public breakpointObserver: BreakpointObserver,
    public mediaMatcher: MediaMatcher
  ) {}

  ngAfterViewInit(): void {
    const breakpoints: string[] = Object.values(gridResponsiveMap);
    this.breakpointObserver.observe(breakpoints).subscribe(() => {
      this.setGutterStyle()
    })
  }

  getGutter(): [number | null, number | null] {
    const results: [number | null, number | null] = [null, null];
    const gutter = this.nsGutter || 0;
    const normalizedGutter = Array.isArray(gutter) ? gutter : [gutter, null];
    normalizedGutter.forEach((item, index) => {
      if (typeof item === 'object' && item !== null) {
        results[index] = null;
        Object.keys(gridResponsiveMap).forEach((screen: string) => {
          const bp = screen as NsBreakpointKey;
          if (this.mediaMatcher.matchMedia(gridResponsiveMap[bp]).matches && item[bp]) {
            results[index] = item![bp];
          }
        })
      } else {
        results[index] = item || null;
      }
    })
    return results;
  }

  setGutterStyle():void {
    const [horizontalGutter, verticalGutter] = this.getGutter();
    console.log(horizontalGutter, verticalGutter)
    this.actualGutter$.next([horizontalGutter, verticalGutter]);
    
    const renderGutter = (style: string, gutter: number | null):void => {
      const el = this.elementRef.nativeElement;
      if (gutter !== null) {
        this.render.setStyle(el, style, `-${gutter / 2}px`);
      }
    }

    renderGutter('margin-left', horizontalGutter);
    renderGutter('margin-right', horizontalGutter);
    renderGutter('margin-top', verticalGutter);
    renderGutter('margin-bottom', verticalGutter);
  }
}
